<?php
namespace app\index\controller;
use think\Controller;
use think\Db;
use think\Session;

header('Access-Control-Allow-Origin:*');
header("Access-Control-Allow-Headers:Origin, X-Requested-With, Content-Type, Accept,USER_ID,TOKEN");
header("Access-Control-Allow-Methods:HEAD, GET, POST, DELETE, PUT, OPTIONS");

//微信支付类
class Wpay extends Controller {
    public $jsApiParameters;
    function build_order_no(){
        return date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
    }
    //获取access_token过程中的跳转uri，通过跳转将code传入jsapi支付页面
    public function jsapi() {
        header("content-type:text/html;charset=utf-8");
        //获取用户id
//        $user_id = Session::get('id');
        $user_id = $_GET['user_id'];
        /**
         * type   作用：区分是微信绑定还是微信支付
         * type == 1      微信绑定
         * type == 2      微信支付
         * */
        $type = $_GET['type'];

        if($type == 1){
            /**
             * 长按二维码跳转到这个方法获取openid
             * 获取openid之后将openid绑定到用户信息
             * */
            vendor('Wpay.Weixinpay.WxPayPubHelper');
            //使用jsapi接口
            $jsApi = new \JsApi_pub();
            //=========步骤1：网页授权获取用户openid============
            //通过code获得openid
            if (!isset($_GET['code'])){
                //触发微信返回code码
                $url = $jsApi->createOauthUrlForCode(urlencode("http://tour.mgtvshop.com/index/Wpay/jsapi?type=1&user_id=".$user_id));
                file_put_contents(RUNTIME_PATH.'url.txt',$url);
                Header("Location: $url");
            }else{
                //获取code码，以获取openid
                $code = $_GET['code'];
                file_put_contents(RUNTIME_PATH.'code.txt',$code);
                $jsApi->setCode($code);
                $openid = $jsApi->getOpenId();
                file_put_contents(RUNTIME_PATH.'getOpenId.txt',$openid);
                $data = array('openid'=>$openid);
                //将openid绑定到用户信息
                $res = Db::table('tp_user')->where('id',$user_id)->update($data);
                if($res){
                    return json(['code' =>200, 'msg' => '绑定微信成功']);
                }else{
                    return json(['code' =>-1, 'msg' => '绑定微信失败']);
                }
            }
        }else{
            /*获取随机订单号*/
            $sn=$this->build_order_no();

            $order_sn = $sn;
            /*充值金额*/
            $num=$_GET['num'];

            $_SESSION['ordfee']=$num;
            if(empty($order_sn)){
                return json(['code' => -2, 'msg' => '订单号为空！']);
            }

            $info = Db::table('tp_user')->where('id',$user_id)->find();
            $openid = $info['openid'];
            if(!$openid){
                return json(['code' => -3, 'msg' => '您还未绑定您的微信，请先进行绑定！']);exit;
            }
            /*if (empty($order_sn)) {
                header('location:'.__ROOT__.'/');
            }*/
            vendor('Wpay.Weixinpay.WxPayPubHelper');
            //使用jsapi接口
            $jsApi = new \JsApi_pub();
            //=========步骤1：网页授权获取用户openid============
            //通过code获得openid
            /*if (!isset($_GET['code'])){
                //触发微信返回code码
                $url = $jsApi->createOauthUrlForCode(urlencode("http://tour.mgtvshop.com/index/Wpay/jsapi?order_sn=".$order_sn."&num=".$num."&type=2&user_id=".$user_id));
                //$url =
                file_put_contents(RUNTIME_PATH.'url.txt',$url);
                //$jsApi->createOauthUrlForCode(\WxPayConf_pub::JS_API_CALL_URL);
                Header("Location: $url");
            }else{
                //获取code码，以获取openid
                $code = $_GET['code'];
                file_put_contents(RUNTIME_PATH.'code.txt',$code);
                $jsApi->setCode($code);
                $openid = $jsApi->getOpenId();
//            $openid = $_GET['openid'];
                file_put_contents(RUNTIME_PATH.'getOpenId.txt',$openid);
            }*/

            $res = array(
                'order_sn' => $order_sn,
                'order_amount' => $_GET['num']
            );
            //=========步骤2：使用统一支付接口，获取prepay_id============
            //使用统一支付接口
            $unifiedOrder = new \UnifiedOrder_pub();
            //设置统一支付接口参数
            //设置必填参数
            //appid已填,商户无需重复填写
            //mch_id已填,商户无需重复填写
            //noncestr已填,商户无需重复填写
            //spbill_create_ip已填,商户无需重复填写
            //sign已填,商户无需重复填写
            $total_fee = $res['order_amount']*100;
            //$total_fee = 1;
            $body = "订单支付{$res['order_sn']}";
            $unifiedOrder->setParameter("openid", $openid);//用户标识
            $unifiedOrder->setParameter("body", $body);//商品描述
            //自定义订单号，此处仅作举例
            $out_trade_no = $res['order_sn'];
            $unifiedOrder->setParameter("out_trade_no", $out_trade_no);//商户订单号
            $unifiedOrder->setParameter("total_fee", $total_fee);//总金额
            //$unifiedOrder->setParameter("attach", "order_sn={$res['order_sn']}");//附加数据
            $unifiedOrder->setParameter("notify_url", \WxPayConf_pub::NOTIFY_URL);//通知地址
            $unifiedOrder->setParameter("trade_type", "JSAPI");//交易类型
            //非必填参数，商户可根据实际情况选填
            //$unifiedOrder->setParameter("sub_mch_id","XXXX");//子商户号
            //$unifiedOrder->setParameter("device_info","XXXX");//设备号
            //$unifiedOrder->setParameter("attach","XXXX");//附加数据
            //$unifiedOrder->setParameter("time_start","XXXX");//交易起始时间
            //$unifiedOrder->setParameter("time_expire","XXXX");//交易结束时间
            //$unifiedOrder->setParameter("goods_tag","XXXX");//商品标记
            //$unifiedOrder->setParameter("openid","XXXX");//用户标识
            //$unifiedOrder->setParameter("product_id","XXXX");//商品ID
            $prepay_id = $unifiedOrder->getPrepayId();
            file_put_contents(RUNTIME_PATH.'prepay_id1.txt',$prepay_id);

            //=========步骤3：使用jsapi调起支付============
            $jsApi->setPrepayId($prepay_id);

            $jsApiParameters = $jsApi->getParameters();
            file_put_contents(RUNTIME_PATH.'jsApiParameters.txt',$jsApiParameters);
            $wxconf = json_decode($jsApiParameters, true);

            if ($wxconf['package'] == 'prepay_id=') {
                $this->error('当前订单存在异常，不能使用支付');
            }
            $this->assign('res', $res);
            $this->assign('jsApiParameters', $jsApiParameters);
            //生成一条订单(充值表里)
            $data=array('ordfee'=>$_GET['num'],'userid'=>$user_id, 'ordtime'=>time(),
                'ordstatus'=>'0','payment_type'=>'1','order_trade'=>$out_trade_no);

            $id = Db::table("tp_order")->insert($data);
            if($id){
//                return json(['code' => 200, 'res' => $res, 'jsApiParameters' => $jsApiParameters]);
//                return $this->view->fetch();
                $this->jsApiParameters = $jsApiParameters;
            }
        }
    }
    public function jsapi_page(){
        $price = isset($_GET['price'])?$_GET['price']:0;
        $jsApiParameters = isset($this->jsApiParameters)?$this->jsApiParameters:'{msg:null}';

        $this->assign('jsApiParameters', $jsApiParameters);
        $this->assign('price', $price);
        return $this->view->fetch('jsapi');
    }

    //异步通知url，商户根据实际开发过程设定
    public function notify_url() {
        vendor('Wpay.Weixinpay.WxPayPubHelper');
        //使用通用通知接口
        $notify = new \Notify_pub();
        //存储微信的回调
        $xml = $GLOBALS['HTTP_RAW_POST_DATA'];
        $notify->saveData($xml);

        //验证签名，并回应微信。
        //对后台通知交互时，如果微信收到商户的应答不是成功或超时，微信认为通知失败，
        //微信会通过一定的策略（如30分钟共8次）定期重新发起通知，
        //尽可能提高通知的成功率，但微信不保证通知最终能成功。
        if($notify->checkSign() == FALSE){
            $notify->setReturnParameter("return_code", "FAIL");//返回状态码
            $notify->setReturnParameter("return_msg", "签名失败");//返回信息
        }else{
            $notify->setReturnParameter("return_code", "SUCCESS");//设置返回码
        }
        $returnXml = $notify->returnXml();
        //==商户根据实际情况设置相应的处理流程，此处仅作举例=======
        //以log文件形式记录回调信息
        //$log_name = "notify_url.log";//log文件路径
        //$this->log_result($log_name, "【接收到的notify通知】:\n".$xml."\n");
        $parameter = $notify->xmlToArray($xml);
        file_put_contents(RUNTIME_PATH.'parameter.txt',json_encode($parameter));

        //$this->log_result($log_name, "【接收到的notify通知】:\n".$parameter."\n");
        if($notify->checkSign() == TRUE){
            if ($notify->data["return_code"] == "FAIL") {
                //此处应该更新一下订单状态，商户自行增删操作
                //$this->log_result($log_name, "【通信出错】:\n".$xml."\n");
                //更新订单数据【通信出错】设为无效订单
                echo 'error';
            }else if($notify->data["result_code"] == "FAIL"){
                //此处应该更新一下订单状态，商户自行增删操作
                //$this->log_result($log_name, "【业务出错】:\n".$xml."\n");
                //更新订单数据【通信出错】设为无效订单
                echo 'error';
            }else{
                //$this->log_result($log_name, "【支付成功】:\n".$xml."\n");
                //我这里用到一个process方法，成功返回数据后处理，返回地数据具体可以参考微信的文档
                if ($this->process($parameter)) {
                    //处理成功后输出success，微信就不会再下发请求了
                  //  echo "nice";
                    echo 'success';
                }else {
                    //没有处理成功，微信会间隔的发送请求
                    echo 'error';
                }
            }
        }
    }
    //订单处理
    private function process($parameter) {
        //file_put_contents('../runtime/test.txt',$parameter['out_trade_no']);
        $time=time();
        //判断是否已经进行过操作
        //$if=$this->db_single("select count(*) as li from tp_order where order_trade = '{$parameter['out_trade_no']}' and ordstatus = '0'");
        $where['order_trade'] = $parameter['out_trade_no'];
        $where['ordstatus'] =1 ;
        $if = Db::table("tp_order")->where($where)->select();
        if($if){
            echo "nice";exit;
        }else{
            //修改订单表
            //$upsql="update tp_order set ordid = '{$parameter['transaction_id']}',ordstatus = '1',openid='{$parameter['openid']}' where order_trade = '{$parameter['out_trade_no']}'";
            //$id=Db::query($upsql);
            $upsql['ordid'] = $parameter['transaction_id'];
            $upsql['ordstatus'] =1;
            $upsql['openid'] = $parameter['openid'];
            $id = Db::table("tp_order")->where(array('order_trade'=>$parameter['out_trade_no']))->update($upsql);
            file_put_contents(RUNTIME_PATH.'order_sql.txt',Db::table('tp_order')->getLastSql());
            if($id){
                //$bsql=$this->db_single("select userid,ordfee from tp_order where order_trade = '{$parameter['out_trade_no']}' and ordstatus = '1'");
                $fin['order_trade'] = $parameter['out_trade_no'];
                $fin['ordstatus'] = 1;
                $bsql = Db::table("tp_order")->where($fin)->find();
                //修改对应的用户余额
                $ordfee = $bsql['ordfee'];
                $userid = $bsql['userid'];

                $sql="update tp_user set money = money+{$ordfee} where id = {$userid}";

                $id=Db::execute($sql);
                if($id){
                    $balance=array('balance_uid'=>$bsql['userid'],'balance_quota'=>$bsql['ordfee'],'balance_describe'=>'充值','create_time'=>$time,'balance_con'=>'微信充值');
                    //$ids=$this->mysql_insert($balance,'tp_balance');
                    $ids = Db::table("tp_balance")->insert($balance);
                    if($ids){
                        echo "支付成功";exit;
                    }
                }
            }else{
               echo '支付失败';exit;
            }
        }
    }

    /**
     * 给二维码添加logo
     * @param $qr_code_url (二维码图片地址
     * @param string $logo
     * (默认值是一张图片
     */
    public function erweima_add_logo($qr_code_url, $logo = '')
    {
        $logo = $logo ? $logo : ROOT_PATH . 'public' . DS . 'static' . DS . 'home' . DS . 'images' . DS . 'erweima_logo.png';
        $QR = $qr_code_url; // 已经生成的原始二维码图

        if ($logo)
        {
            $QR = imagecreatefromstring(file_get_contents($QR));
            $logo = imagecreatefromstring(file_get_contents($logo));
            $QR_width = imagesx($QR); // 二维码图片宽度
            $QR_height = imagesy($QR); // 二维码图片高度
            $logo_width = imagesx($logo); // logo图片宽度
            $logo_height = imagesy($logo); // logo图片高度
            $logo_qr_width = $QR_width / 6;
            $scale = $logo_width / $logo_qr_width;
            $logo_qr_height = $logo_height / $scale;
            $from_width = ($QR_width - $logo_qr_width) / 2;
            // 重新组合图片并调整大小
            imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height);
        }
        // 输出图片
        imagepng($QR, $qr_code_url);
    }
    public function get_qr_code() {
//        $order_id = input('param.order_id');
        $user_id = $_GET['user_id'];//用户id
        // 二维码不存在 生成二维码
        vendor('Wxpay.example.phpqrcode.phpqrcode');

        $obj = new \QRcode();
        // 处理路径

        $root_path = ROOT_PATH . 'public' . DS;
        $upload_path = 'uploads' . DS . 'qr_code' . DS;

        $file_name = $user_id . '.png';
        $dir = $root_path . $upload_path;
        if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
        }

        $erweima_image = $upload_path . $file_name; // 出库二维码地址
        $erweima_url = $root_path . $erweima_image;

//        $erweima_text = input('param.url');
        $erweima_text = 'http://tour.mgtvshop.com/index/wpay/jsapi?type=1&user_id='.$user_id;

        $obj->png($erweima_text, $erweima_url, '', 6, 2); // 生成二维码

//        $logo = $root_path . 'static/home/images/qr_logo.png';
        $logo = $root_path . '/static/index/img/logo.jpg';

        $this->erweima_add_logo($erweima_url, $logo); // 添加logo

        return json(['code' => 200, 'path' => $erweima_image]);
//        return $this->view->fetch();
    }

}